package com.example.userservice.controller;

import com.example.commom.enums.RespDescEnum;
import com.example.commom.enums.StatusCodeEnum;
import com.example.commom.exception.CustomException;
import com.example.commom.global.AppVariable;
import com.example.commom.redis.RedisUtils;
import com.example.feign.entity.User;
import com.example.feign.result.AjaxResult;
import com.example.commom.utils.JwtUtils;
import com.example.userservice.service.UserService;
import com.example.userservice.serviceImpl.UserServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * 用户注册
 *
 * @author 软工2104-李家强-2100770248
 * @since 2023-09-19
 */
@Slf4j
@Transactional
@RestController
@ApiOperation(value = "用户服务相关接口")
@RequestMapping("/user")
@Api(value = "用户服务相关接口", tags = "用户服务相关接口")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     *  通过用户id 查询详细信息
     */
    @GetMapping("/{id}")
    public AjaxResult getUserInfoById(@PathVariable("id") Long id,
                                      @RequestHeader("token") String token) {
        return AjaxResult.success(userService.getById(id));
    }

    /**
     *  登录
     */
    @PostMapping("/login")
    @ApiOperation(value = "用户登录接口", notes = "参数是: username, password")
    public AjaxResult login(@Validated @RequestBody User user,
                            @RequestHeader(value = "token", required = false) String userToken) {

        // 查询数据库, 查看密码是否正确
        User userInfo = userService.getUserByName(user.getUsername());

        if (userInfo == null) {
            return AjaxResult.fail(StatusCodeEnum.FAILED.getCode(), RespDescEnum.AccountNotExistence.getValue());
        }

        // 判断账号是否被封禁
        if (userInfo.getIsBanned()) {
            return AjaxResult.fail(StatusCodeEnum.FAILED.getCode(), RespDescEnum.AccountIsBanned.getValue());
        }

        // 检查密码
        if (!userInfo.getPassword().equals(user.getPassword())) {
            return AjaxResult.fail(StatusCodeEnum.FAILED.getCode(),RespDescEnum.AccountVerifyFailed.getValue());
        }

        String redisToken = RedisUtils.getJwtTokenFromRedis(RedisUtils.getTokenRedisKey(
                userInfo.getType(), userInfo.getUserId()
        ));
        if (redisToken != null) {
            if (!redisToken.equals(userToken)) {
                return AjaxResult.fail(StatusCodeEnum.FAILED.getCode(), RespDescEnum.AccountIsLogin.getValue());
            }
        }

        // 正常的账号, 进行登录
        HashMap<String, Object> result = userService.successLogin(userInfo);

        return AjaxResult.success(StatusCodeEnum.OK.getCode(), result);
    }

    /**
     *  退出登录
     */
    @PostMapping("/exit")
    @ApiOperation(value = "退出登录", notes = "参数无")
    public AjaxResult exit(@RequestHeader("token") String token) {

        return userService.exit(token);
    }

    /**
     *  注册
     */
    @PostMapping("/register")
    @ApiOperation(value = "用户注册接口", notes = "参数是一个用户对象")
    public AjaxResult register(@Validated @RequestBody User user) {

       return userService.register(user);
    }

    /**
     *  输出一张验证码
     */
    @GetMapping("imgCode")
    @ApiOperation(value = "获取验证接口", notes = "无参数")
    public void getCode(HttpServletRequest request, HttpServletResponse response) throws IOException {

        userService.getCode(request, response);
    }


    /**
     *  个人信息管理(修改普通信息)
     */
    @PostMapping("/update")
    @ApiOperation(value = "修改普通用户信息", notes = "参数是id, 和要修改的内容")
    public AjaxResult update(@RequestBody User user, @RequestHeader("token") String token) {

        if (user.getUserId() == null) {
            return AjaxResult.fail(StatusCodeEnum.FAILED.getCode(), RespDescEnum.MissRequiredParameter.getValue());
        }

        user.setType(null);
        user.setIsBanned(null);
        user.setPhoto(null);

        return userService.updateUserInfo(user, token);
    }

    /**
     *  用户上传头像
     */
    @PostMapping("/image")
    @ApiOperation(value = "用户上传头像", notes = "修改头像")
    public AjaxResult upLoadPhoto(@RequestPart("file") MultipartFile multipartFile,
                                  @RequestParam("userId") String userId,
                                  @RequestHeader("token") String token) {

        if (!StringUtils.hasLength(userId)) {
            return AjaxResult.fail(StatusCodeEnum.FAILED.getCode(),RespDescEnum.MissRequiredParameter.getValue());
        }

        // 判断权限
        String tokenUserId = JwtUtils.getUserIdByToken(token);
        if (!(userId + "").equals(tokenUserId)) {
            return AjaxResult.fail(StatusCodeEnum.UNAUTHORIZED.getCode(), StatusCodeEnum.UNAUTHORIZED.getMsg());
        }

        User userInfo = userService.getById(userId);
        if (userInfo == null) {
            return AjaxResult.fail(StatusCodeEnum.FAILED.getCode(), RespDescEnum.AccountNotExistence.getValue());
        }

        return userService.upLoadPhoto(multipartFile, userInfo);
    }


    @GetMapping("/getUserImages")
    @ResponseBody
    public Resource getImage(@RequestParam("imageName") String imageName) {
        // 这里假设您的静态资源图片存放在 static/images 目录下
        // 通过 ResourceLoader 加载静态资源
        return new ClassPathResource(AppVariable.USER_IMAGE_URL + imageName);
    }


    @PostMapping("/exist/{userId}")
    @ApiOperation(value = "查看是否存在该用户", notes = "参数为用户 id")
    public boolean userIsExist(@PathVariable("userId") Long userId) {
        if (userId == null) {
            return false;
        }

        return userService.getById(userId) != null;
    }

    /**
     *  获取两个用户的共同关注
     */
    @GetMapping("/common/{id}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "要查看的用户id", dataType = "long",
                    paramType = "path", required = true),
    })
    @ApiOperation(value = "获取两个用户的共同关注", notes = "目标用户id")
    public AjaxResult followCommons(@PathVariable("id") String id,
                                    @RequestHeader("token") String token) {

        // 拿到登录用户 id
        String userId = JwtUtils.getUserIdByToken(token);
        if (userId == null) {
            return AjaxResult.fail(StatusCodeEnum.Redirect.getCode(), StatusCodeEnum.Redirect.getMsg());
        }

        return userService.followCommons(id, userId);
    }

}
